package com.lagou.edu.factory;

import com.alibaba.druid.util.StringUtils;
import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.annotation.Transactional;
import org.reflections.Reflections;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


public class BeanFactory {



    private static Map<String,Object> map = new HashMap<>();

    public static void main(String[] args) {

    }
    static {
        try{
            //扫描包
            Reflections edus = new Reflections("com.lagou.edu");
            //获取所有Service注解的类
            Set<Class<?>> clazzs = edus.getTypesAnnotatedWith(Service.class);
            //遍历
            for (Class<?> clazz:clazzs) {
                //实力化
                Object object = clazz.newInstance();
                Service service = clazz.getAnnotation(Service.class);
                //value值是否填写
                if(StringUtils.isEmpty(service.value())){
                    String[] names = clazz.getName().split("\\.");
                    map.put(names[names.length-1], object);
                }else{
                    map.put(service.value(), object);
                }
            }
            for(Map.Entry<String, Object> entrySet: map.entrySet()) {
                Object obj = entrySet.getValue();
                Class clazz = obj.getClass();
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    //是否有Autowired，有使用注解则注入
                    if (field.isAnnotationPresent(Autowired.class)&& field.getAnnotation(Autowired.class).value()) {
                        String[] names = field.getType().getName().split("\\.");
                        String name = names[names.length - 1];
                        Method[] methods = clazz.getMethods();
                        for (int j = 0; j < methods.length; j++) {
                            Method method = methods[j];
                            if (method.getName().equalsIgnoreCase("set" + name)) {
                                method.invoke(obj, map.get(name));
                            }
                        }
                    }
                }
                if(clazz.isAnnotationPresent(Transactional.class)){
                    //获取代理工厂
                    ProxyFactory proxyFactory = (ProxyFactory) BeanFactory.getBean("proxyFactory");
                    Class[] face = clazz.getInterfaces();//获取类c实现的所有接口
                    //判断对象是否实现接口
                    if(face!=null&&face.length>0){
                        //实现使用JDK
                        obj = proxyFactory.getJdkProxy(obj);
                    }else{
                        //没实现使用CGLIB
                        obj = proxyFactory.getCglibProxy(obj);
                    }
                }
                // 把处理之后的object重新放到map中
                map.put(entrySet.getKey(),obj);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }




    // 任务二：对外提供获取实例对象的接口（根据id获取）
    public static  Object getBean(String id) {
        return map.get(id);
    }

}
